package com.github.cyf.util;

import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.Configuration;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * @author chenyifan
 * @create 2024-04-13 22:03
 */
public class ExecutorUtil {

    /**
     * 根据原始 sql，获取实际执行的 sql
     * @param boundSql
     * @return
     */
    public static String getRealSql(BoundSql boundSql) {
        // 获取 mapper 里面方法上的参数值列表
        Object sqlParameter = boundSql.getParameterObject();
        // sql 语句里面需要的参数列表，sqlParameter 里面的每个参数不一定都会用到
        List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();
        // 原始 sql，去掉 sql 多余的空格
        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        if (parameterMappingList.size() > 0 && sqlParameter != null) {
            // sql 语句里面的 ? 替换成真实的参数
            MetaObject metaObject = SystemMetaObject.forObject(sqlParameter);
            for (ParameterMapping parameterMapping : parameterMappingList) {
                // sql 里面的参数名称
                String propertyName = parameterMapping.getProperty();
                if (metaObject.hasGetter(propertyName)) {
                    // 获取对应的参数值
                    Object obj = metaObject.getValue(propertyName);
                    sql = sql.replaceFirst("\\?", getParameterValue(obj));
                }
            }
        }
        return sql;
    }

    /**
     * 获取参数对应的 string 值
     *
     * @param obj
     * @return
     */
    private static String getParameterValue(Object obj) {
        if (obj == null) {
            return "";
        }
        if (obj instanceof String) {
            return  "'"  + obj + "'";
        } else {
            return obj.toString();
        }
    }
}
